package de.axa.smartfix.monitoring.model;

import java.beans.PropertyChangeEvent;
import java.util.Date;
import java.util.Observable;

/**
 * AbstractMonitor implementiert Standardausprägungen des Interfaces
 * IMonitor. Um nicht allzuviel selbst implemtieren zu müssen, sollte hiervon
 * abgeleitet werden. Zusätzlich wird das Beobachter-Muster verfügbar gemacht, durch
 * Veerbung von Observable.
 * 
 * @author tobias
 * 
 */
public abstract class AbstractMonitor extends Observable implements
		IMonitor {

	private final static IMonitor[] EMPTY = new IMonitor[0];

	private String name;

	private String description;

	private Object parent = null;

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.axa.smartfix.monitoring.model.IMonitor#add(de.axa.smartfix.monitoring.model.IMonitor)
	 */
	public void add(IMonitor m) {
		throw new UnsupportedOperationException();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.axa.smartfix.monitoring.model.IMonitor#clear()
	 */
	public void clear() {
		throw new UnsupportedOperationException();
	}

	protected void fireEvent() {
		fireEvent(null);
	}

	protected void fireEvent(Object o) {
		setChanged();
		notifyObservers(o);
	}

	public IMonitor[] getChildren() {
		return EMPTY;
	}

	public int getCount() {
		int sum = 0;

		for (IMonitor location : getChildren()) {
			sum += location.getCount();
		}

		return sum;
	}

	public String getDescription() {
		return this.description;
	}

	public String getName() {
		return this.name;
	}

	public Date getOldest() {
		Date startDate = IMonitor.NO_DATE_AVAILABLE;

		for (Object location : getChildren()) {
			Date newDate = ((IMonitor) location).getOldest();

			if (newDate == IMonitor.NO_DATE_AVAILABLE)
				continue;

			if (startDate == IMonitor.NO_DATE_AVAILABLE
					|| newDate.before(startDate))
				startDate = newDate;
		}

		return startDate;
	}

	public Object getParent() {
		return this.parent;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.axa.smartfix.monitoring.model.IMonitor#remove(de.axa.smartfix.monitoring.model.IMonitor)
	 */
	public void remove(IMonitor m) {
		throw new UnsupportedOperationException();
	}

	public void setDescription(String description) {
		PropertyChangeEvent pe = new PropertyChangeEvent(this, PROPERTY_DESCRIPTION,
				this.description, description);
		this.description = description;
		fireEvent(pe);
	}

	public void setName(String name) {
		PropertyChangeEvent pe = new PropertyChangeEvent(this, PROPERTY_NAME, this.name, name);
		this.name = name;
		fireEvent(pe);
	}

	public void setParent(Object o) {
		PropertyChangeEvent pe = new PropertyChangeEvent(this, PROPERTY_PARENT,
				this.parent, o);
		this.parent = o;
		fireEvent(pe);
	}

	public void update() {
		long oldCount = getCount();
		Date oldDate = getOldest();

		for (IMonitor location : getChildren()) {
			location.update();
		}
		
		PropertyChangeEvent pe = new PropertyChangeEvent(this, PROPERTY_COUNT, oldCount, getCount());
		fireEvent(pe);
		pe = new PropertyChangeEvent(this, PROPERTY_OLDEST, oldDate, getOldest());
		fireEvent(pe);
	}

}
